package com.linkstec.mot.util;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import redis.clients.jedis.JedisCluster;

public class RedisClusterUtil {

	private static final Logger logger = LoggerFactory
			.getLogger(RedisClusterUtil.class);

	private static JedisCluster jedisCluster = SpringContextUtil
			.getBean("jedisCluster");

	private static String keyNameSpace = null;

	public static void set(String key, Object value) throws Exception {
		String strVal = null;
		try {
			if (value != null) {
				if (!(value instanceof String)) {
					strVal = JSON.toJSONString(value);
				} else {
					strVal = (String) value;
				}
			}
			jedisCluster.set(keyNameSpace + key, strVal);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	// set key-value and set key expire time
	public static void setExpire(String key, int expireTime, Object value)
			throws Exception {
		String strVal = null;
		try {
			if (value != null) {
				if (!(value instanceof String)) {
					strVal = JSON.toJSONString(value);
				} else {
					strVal = (String) value;
				}
			}
			jedisCluster.setex(keyNameSpace + key, expireTime, strVal);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	// get value by key
	public static <T> T get(String key, Class<T> clazz) throws Exception {
		T value = null;
		try {
			String strVal = jedisCluster.get(keyNameSpace + key);
			if (strVal != null) {
				value = (T) JSON.parseObject(strVal, clazz);
			}
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
		return value;
	}

	public static void putHashMap(String key, Map<String, String> map)
			throws Exception {
		try {
			jedisCluster.hmset(keyNameSpace + key, map);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	// get hash map element
	public static String hget(String key, String hashKey) throws Exception {
		String result = null;
		try {
			result = jedisCluster.hget(keyNameSpace + key, hashKey);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
		return result;
	}

	public static void hSet(String key, String hashKey, Object hashValue)
			throws Exception {
		String strVal = null;
		try {
			if (hashValue != null) {
				if (!(hashValue instanceof String)) {
					strVal = JSON.toJSONString(hashValue);
				} else {
					strVal = (String) hashValue;
				}
			}
			jedisCluster.hset(keyNameSpace + key, hashKey, strVal);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	public static boolean hContains(String key, String hashKey)
			throws Exception {
		boolean result = false;
		try {
			result = jedisCluster.hexists(keyNameSpace + key, hashKey);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}

		return result;
	}

	public static Set<String> hKeys(String key) throws Exception {
		Set<String> result = null;
		try {
			result = jedisCluster.hkeys(keyNameSpace + key);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}

		return result;
	}

	public static void hDel(String key, String hashKey) throws Exception {
		try {
			jedisCluster.hdel(keyNameSpace + key, hashKey);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	public static void del(String key) throws Exception {
		try {
			jedisCluster.del(keyNameSpace + key);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	public static void del(Collection<String> keys) throws Exception {
		try {
			String[] keyArray = (String[]) keys.toArray();
			for (String item : keyArray) {
				item = keyNameSpace + item;
				jedisCluster.del(item);
			}
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	public static void addSet(String key, Object value) throws Exception {
		String strVal = null;
		try {
			if (value != null) {
				if (!(value instanceof String)) {
					strVal = JSON.toJSONString(value);
				} else {
					strVal = (String) value;
				}
			}
			jedisCluster.sadd(keyNameSpace + key, strVal);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
	}

	public static boolean contains(String key, Object value) throws Exception {
		String strVal = null;
		boolean result = false;
		try {
			if (value != null) {
				if (!(value instanceof String)) {
					strVal = JSON.toJSONString(value);
				} else {
					strVal = (String) value;
				}
			}
			result = jedisCluster.sismember(keyNameSpace + key, strVal);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
		return result;
	}

	public static Set<String> sMembers(String key) throws Exception {
		Set<String> result = null;
		try {
			result = jedisCluster.smembers(keyNameSpace + key);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
		return result;
	}

	public static Long incrBy(final String key, final long integer)
			throws Exception {
		Long result;
		try {
			result = jedisCluster.incrBy(keyNameSpace + key, integer);
		} catch (Exception e) {
			logger.error(ExceptionTracker.trace(e));

			throw e;
		}
		return result;
	}

	static {
		// 初始化key的前缀
		Map<String, String> redisClusterSetting = ConfigUtil
				.getConfigMap("redis-cluster");
		keyNameSpace = redisClusterSetting.get("redis.cluster.key.prefix");
	}
}
